package com.mofum.msdom.excel.writer.impl;

import com.mofum.msdom.excel.annotation.parser.impl.ATColumnParser;
import com.mofum.msdom.excel.annotation.parser.impl.ATWorkbookParser;
import com.mofum.msdom.excel.converter.ExcelConverter;
import com.mofum.msdom.excel.converter.TypeConverter;
import com.mofum.msdom.excel.metadata.MPColumn;
import com.mofum.msdom.excel.metadata.MPWorkbook;
import com.mofum.msdom.excel.reader.impl.AnnotationExcelReaderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map;

/**
 * 数据写入器
 *
 * @author 1615690513@qq.com
 * @since 2018/11/24 0021 15:53
 */
public class AnnotationExcelWriterImpl<Data> extends TypeExcelWriterImpl<Data> {

    public static Logger logger = LoggerFactory.getLogger(AnnotationExcelWriterImpl.class);

    @Override
    public AnnotationExcelWriterImpl start(OutputStream output) {
        if (dataClass == null) {
            throw new RuntimeException("Output data type must be set!");
        }

        ATWorkbookParser atWorkbookParser = new ATWorkbookParser();

        Map<Type, MPWorkbook> maps = null;
        try {
            maps = atWorkbookParser.parseType(dataClass);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }

        if (maps.keySet().size() == 0) {
            throw new RuntimeException("No  annotations were detected in this class (" + dataClass.toString() + ") !");
        }

        this.setOutputStream(output);

        mpWorkbook = maps.get(dataClass);

        cache(mpWorkbook.getCache());

        sheets(mpWorkbook.getSheets());

        setStartStatus(true);
        return this;
    }

    @Override
    public AnnotationExcelWriterImpl dataType(Class<Data> dataClass) {
        this.setDataClass(dataClass);

        try {

            //创建解析器
            ATColumnParser<Data> columnParser = new ATColumnParser<Data>();

            //解析出列
            Map<Field, MPColumn> columnMap = columnParser.parseField(dataClass.newInstance());

            //设置列Map
            this.setColumnMap(columnMap);

            //转换成索引Map
            Map<Integer, String> indexMap = columnMapToIndexMap(columnMap);

            //设置索引Map
            this.setIndexMap(indexMap);

            Map<Field, ExcelConverter> excelConverterMap = columnMapToExcelConverterMap(columnMap);

            this.setExcelConverterMap(excelConverterMap);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }

        return this;
    }

}
